/**
 * 
 */
package com.swg.cocobox.filetransfer;

import java.io.IOException;
import java.net.InetAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

import com.swg.cocobox.filetransfer.command.ClientCommand;
import com.swg.cocobox.filetransfer.command.ClientCommandFactory;
import com.swg.cocobox.filetransfer.command.Command;
import com.swg.cocobox.filetransfer.command.CommandEventProcessor;
import com.swg.cocobox.filetransfer.command.CommandEventSupport;
import com.swg.cocobox.filetransfer.data.DataTransfer;
import com.swg.cocobox.server.ReadWriteServer;

/**
 * @author satriaprayoga
 *
 */
public abstract class FileServer extends ReadWriteServer{
	
	private CommandEventSupport eventSupport;
	private CommandEventProcessor eventProcessor;
	
	private DataTransfer dataTransfer;
	
	private ClientCommandFactory clientCommandFactory;

	public FileServer(InetAddress address, int port) throws IOException {
		super(address, port);
	}

	public FileServer(String host, int port) throws IOException {
		super(host, port);
	}
	
	public void reply(SocketChannel channel,byte[] data)throws IOException{
		this.send(channel, data);
	}
	
	public void reply(SocketChannel channel,Command command)throws IOException{
		reply(channel, command.getBytes());
	}

	@Override
	protected void read(SelectionKey key) throws IOException {
		SocketChannel socketChannel=(SocketChannel)key.channel();
		readBuffer.clear();
		int numRead;
		try{
			numRead=socketChannel.read(readBuffer);
		}catch(IOException e){
			key.cancel();
			socketChannel.close();
			return ;
		}
		if(numRead==-1){
			key.cancel();
			key.channel().close();
			return ;
		}
		byte[] copy=new byte[numRead];
		System.arraycopy(readBuffer.array(), 0, copy, 0, numRead);
		ClientCommand command=getClientCommandFactory().parseCommand(copy);
		handle(socketChannel, command);
		
	}
	protected abstract void handle(SocketChannel channel,ClientCommand command) throws IOException;
	
	public void setEventProcessor(CommandEventProcessor eventProcessor) {
		this.eventProcessor = eventProcessor;
	}
	
	public void setEventSupport(CommandEventSupport eventSupport) {
		this.eventSupport = eventSupport;
	}
	
	public CommandEventProcessor getEventProcessor() {
		return eventProcessor;
	}
	
	public CommandEventSupport getEventSupport() {
		return eventSupport;
	}
	
	public void setDataTransfer(DataTransfer dataTransfer) {
		this.dataTransfer = dataTransfer;
	}
	
	public DataTransfer getDataTransfer() {
		return dataTransfer;
	}
	
	public void setClientCommandFactory(
			ClientCommandFactory clientCommandFactory) {
		this.clientCommandFactory = clientCommandFactory;
	}
	
	public ClientCommandFactory getClientCommandFactory() {
		return clientCommandFactory;
	}

}
